﻿using HarmonyLib;
using RimWorld;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using Verse;
using Verse.Noise;
using static HarmonyLib.Code;

namespace Meow
{
    public class CompProperties_PawnRenderAdjuster : CompProperties
    {
        public bool offsetOnlyStand = true;
        //public float offsetScale = 1;
        public Vector3 eastOffset;
        public Vector3 westOffset;
        public Vector3 southOffset;
        public Vector3 northOffset;
        public Vector3 eastOffsetHead;
        public Vector3 westOffsetHead;
        public Vector3 southOffsetHead;
        public Vector3 northOffsetHead;

        public float scale = 1;
        public float headScale = 1;
        public float headOffsetScale = 1;


        //static Dictionary<string, CompProperties_PawnRenderAdjuster> AllAdjusterInfo = new Dictionary<string, CompProperties_PawnRenderAdjuster>();

        public CompProperties_PawnRenderAdjuster()
        {
            compClass = typeof(Comp_PawnRenderAdjuster);
        }

        //public override void PostLoadSpecial(ThingDef parent)
        //{
        //    AllAdjusterInfo.SetOrAdd(parent.defName, this);
        //}
    }
    
    [StaticConstructorOnStartup]
    public class Comp_PawnRenderAdjuster : ThingComp
    {
    }

    
    public class PawnRenderPatch
    {

        [HarmonyPatch(typeof(PawnRenderer), "ParallelGetPreRenderResults")]
        public class PawnRenderPatch_ParallelGetPreRenderResults
        {
            [HarmonyPrefix]
            public static void ChangeOffset(PawnRenderer __instance, ref Vector3 drawLoc, Rot4? rotOverride = null)
            {
                var pr = Traverse.Create(__instance);
                var pawn = (Pawn)(pr.Field("pawn").GetValue());

                PawnRenderFlags pawnRenderFlags = PawnRenderFlags.None;
                if (!pawn.health.hediffSet.HasHead)
                {
                    pawnRenderFlags |= PawnRenderFlags.HeadStump;
                }
                if (pawnRenderFlags.FlagSet(PawnRenderFlags.Portrait))
                {
                    return;
                }

                var props = pawn.def.comps.FirstOrDefault(p => p is CompProperties_PawnRenderAdjuster) as CompProperties_PawnRenderAdjuster;
                if (props != null && (pawn.GetPosture() == PawnPosture.Standing || !props.offsetOnlyStand))
                {
                    Rot4 rot = rotOverride ?? pawn.Rotation;
                    var offset = Vector3.zero;
                    switch (rot.AsInt)
                    {
                        case 0: offset = props.northOffset; break; // North
                        case 1: offset = props.eastOffset; break; // East
                        case 2: offset = props.southOffset; break; // South
                        case 3: offset = props.westOffset; break; // West
                    }
                    //offset *= props.offsetScale;
                    drawLoc += offset;
                }
            }

        }


        [HarmonyPatch(typeof(PawnRenderer), "BaseHeadOffsetAt")]
        public class PawnRenderPatch_BaseHeadOffsetAt
        {
            [HarmonyPostfix]
            public static void BaseHeadOffsetAt(PawnRenderer __instance, ref Vector3 __result, ref Rot4 rotation)
            {
                var pr = Traverse.Create(__instance);
                var pawn = (Pawn)(pr.Field("pawn").GetValue());
                var props = pawn.def.comps.FirstOrDefault(p => p is CompProperties_PawnRenderAdjuster) as CompProperties_PawnRenderAdjuster;

                if (props != null)
                {
                    __result = new Vector3(__result.x * props.headOffsetScale, __result.y, __result.z * props.headOffsetScale);
                }

                if (pawn == null)
                {
                    Log.Warning($"PawnRenderer_BaseHeadOffsetAt: pawn is null ({__instance}");
                }
            }

        }


        [HarmonyPatch(typeof(PawnRenderNodeWorker), "ScaleFor")]
        public class PawnRenderPatch_ScaleFor
        {
            [HarmonyPostfix]
            public static void ScaleForPatch(ref Vector3 __result, PawnRenderNode node, PawnDrawParms parms)
            {
                Pawn pawn = parms.pawn;
                if (pawn == null)
                {
                    return;
                }
                var pp = pawn.def.comps.FirstOrDefault(p => p is CompProperties_PawnRenderAdjuster) as CompProperties_PawnRenderAdjuster;
                if (pp == null)
                    return;

                double num = pp.scale;
                double num2 = __result.x;
                double num3 = __result.z;
                if (node.parent == null || node.parent.Props.tagDef != PRADefs.Root)
                {
                    return;
                }

                if (pawn.RaceProps.Humanlike)
                {
                    if (node is PawnRenderNode_Body)
                    {
                        __result.x = (float)(num2 * num);
                        __result.z = (float)(num3 * num);
                    }
                    else if (node is PawnRenderNode_Head)
                    {
                        double num4 = pp.headScale;
                        __result.x = (float)(num2 * num4);
                        __result.z = (float)(num3 * num4);
                    }
                }
                else
                {
                    __result.x = (float)(num2 * num);
                    __result.z = (float)(num3 * num);
                }
            }
        }

    }


}
